Skip to content

feat(minor): Disable jemalloc using package traits#347

Open
JaapWijnen wants to merge 6 commits intoordo-one:mainfrom
JaapWijnen:disable-jemalloc-using-package-traits
Open

feat(minor): Disable jemalloc using package traits#347
JaapWijnen wants to merge 6 commits intoordo-one:mainfrom
JaapWijnen:disable-jemalloc-using-package-traits

Conversation

@JaapWijnen
Copy link

Description

This is a first attempt at enabling/disable jemalloc using package traits #316
This shows off what a trait based implementation could look like. But I'm not exactly sure what the expected behaviour would be on unsupported platforms. So that probably needs some more discussion.

How Has This Been Tested?

I performed a build and ran the tests with and without the trait enabled.
The build succeeds on Mac but running tests (with the trait enabled) fails with a segmentation error.
I'm not entirely sure where this is coming from but seems to fail once we add package-jemalloc to the package dependencies. Regardless of if it is actually used by package-benchmark this seems to crash running swift test --traits EnableJemalloc
This user experience should be improved ofcourse. Which I'm hoping to discuss in the PR.

Minimal checklist:

  • I have performed a self-review of my own code
  • I have added DocC code-level documentation for any public interfaces exported by the package
  • I have added unit and/or integration tests that prove my fix is effective or that my feature works

@JaapWijnen
Copy link
Author

This PR title should have been marked with feat: I can't seem to edit the PR title however. @hassila

@hassila
Copy link
Contributor

hassila commented Feb 9, 2026

Thanks @JaapWijnen - but we will soon remove the jemalloc dependency completely through #333 - although that will require a 6.3 toolchain - so maybe worth landing this for 6.0-6.2 support regardless - @JaapWijnen what is you earliest supported toolchain at this point? @supersonicbyte over to you

@supersonicbyte
Copy link
Contributor

Thanks @JaapWijnen - but we will soon remove the jemalloc dependency completely through #333 - although that will require a 6.3 toolchain - so maybe worth landing this for 6.0-6.2 support regardless - @JaapWijnen what is you earliest supported toolchain at this point? @supersonicbyte over to you

I agree this is probably worth landing for 6.0 - 6.2. Will do an extensive PR review soon.

@JaapWijnen
Copy link
Author

Oh that's great!
@hassila what do you mean exactly? The earliest supported toolchain of this approach? It still supports 5.9 but if you use 6.1 you can use the trait to enable jemalloc. (except it is segfaulting on mac which I'd like to understand why, but currently don't have a clue yet)

@hassila
Copy link
Contributor

hassila commented Feb 9, 2026

Yeah, when 6.3 lands we will bump this package to 6.1-6.2 for the old jemalloc and 6.3 for the new malloc interposer (that requires bug fixes from SPM that only exist in 6.3...)

@JaapWijnen
Copy link
Author

Ah I see. Awesome. Yeah we'll be moving to 6.3 as soon as it lands so that's great to hear :) Thanks!

@supersonicbyte supersonicbyte changed the title Disable jemalloc using package traits feat(minor): Disable jemalloc using package traits Feb 11, 2026
@supersonicbyte
Copy link
Contributor

@JaapWijnen everything looks good! just a quick comment. In order to fix the build for linux we should add @preconcurrency annotations in BenchmarkCommandPlugin.swift before the imports:

#if canImport(Darwin)
@preconcurrency import Darwin
#elseif canImport(Glibc)
@preconcurrency import Glibc
#elseif canImport(Musl)
@preconcurrency import Musl
#else
#error("Unsupported Platform")
#endif

Regarding the crash when running swift test --traits EnableJemalloc it a known issue:
jemalloc/jemalloc#2362
#60

It's a bug that happens when xctest runs with jemalloc.

Comment on lines 31 to 45
.target(
name: "Benchmark",
dependencies: [
.product(name: "Histogram", package: "hdrhistogram-swift"),
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SystemPackage", package: "swift-system"),
.byNameItem(name: "CDarwinOperatingSystemStats", condition: .when(platforms: [.macOS, .iOS])),
.byNameItem(name: "CLinuxOperatingSystemStats", condition: .when(platforms: [.linux])),
.product(name: "Atomics", package: "swift-atomics"),
"SwiftRuntimeHooks",
"BenchmarkShared",
.product(name: "jemalloc", package: "package-jemalloc", condition: .when(platforms: [.macOS, .linux], traits: ["EnableJemalloc"])),
],
swiftSettings: [.swiftLanguageMode(.v5)]
),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical Bug: Missing compilation condition definition for EnableJemalloc trait

The code uses #if EnableJemalloc in source files (MallocStatsProducer+jemalloc.swift and OperatingSystemAndMallocTests.swift), but the Benchmark target doesn't define EnableJemalloc as a compilation condition. Package traits only control dependency resolution - they don't automatically become preprocessor flags.

This causes:

  • The jemalloc dependency gets linked when the trait is enabled
  • But the code using jemalloc is never compiled (the #if EnableJemalloc blocks are always skipped)
  • This creates a broken state where the dependency exists but is unused

Fix: Add the compilation condition to swiftSettings:

.target(
    name: "Benchmark",
    dependencies: [...],
    swiftSettings: [
        .swiftLanguageMode(.v5),
        .define("EnableJemalloc", .when(traits: ["EnableJemalloc"]))
    ]
)

The same fix should be applied to BenchmarkTests target (lines 112-131) which also likely needs this compilation condition for its test code.

Suggested change
.target(
name: "Benchmark",
dependencies: [
.product(name: "Histogram", package: "hdrhistogram-swift"),
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SystemPackage", package: "swift-system"),
.byNameItem(name: "CDarwinOperatingSystemStats", condition: .when(platforms: [.macOS, .iOS])),
.byNameItem(name: "CLinuxOperatingSystemStats", condition: .when(platforms: [.linux])),
.product(name: "Atomics", package: "swift-atomics"),
"SwiftRuntimeHooks",
"BenchmarkShared",
.product(name: "jemalloc", package: "package-jemalloc", condition: .when(platforms: [.macOS, .linux], traits: ["EnableJemalloc"])),
],
swiftSettings: [.swiftLanguageMode(.v5)]
),
.target(
name: "Benchmark",
dependencies: [
.product(name: "Histogram", package: "hdrhistogram-swift"),
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SystemPackage", package: "swift-system"),
.byNameItem(name: "CDarwinOperatingSystemStats", condition: .when(platforms: [.macOS, .iOS])),
.byNameItem(name: "CLinuxOperatingSystemStats", condition: .when(platforms: [.linux])),
.product(name: "Atomics", package: "swift-atomics"),
"SwiftRuntimeHooks",
"BenchmarkShared",
.product(name: "jemalloc", package: "package-jemalloc", condition: .when(platforms: [.macOS, .linux], traits: ["EnableJemalloc"])),
],
swiftSettings: [
.swiftLanguageMode(.v5),
.define("EnableJemalloc", .when(traits: ["EnableJemalloc"]))
]
),

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@JaapWijnen
Copy link
Author

@JaapWijnen everything looks good! just a quick comment. In order to fix the build for linux we should add @preconcurrency annotations in BenchmarkCommandPlugin.swift before the imports:

@supersonicbyte Done!

@supersonicbyte
Copy link
Contributor

@JaapWijnen thanks!

I removed the Package.resolved in: #348. Could you please delete it also from the PR so we get the CI jobs passing.

One more thing, @hassila actually noticed that the trait EnableJemalloc will actually break for current users since the default behavior was that jemalloc was enabled by default and you have to pass the environment variable BENCHMARK_DISABLE_JEMALLOC in order to disable it.

In order to preserve backward compatibility could you flip the logic so:

  • we have the trait enabled by default
  • the user runs swift build/test --disable-default-traits in order to disable the trait

Additionally, we can also rename the trait to Jemalloc.

Sorry for the additional comment, I should have seen this in the first review pass.

@JaapWijnen
Copy link
Author

Good point! All done 👍

@JaapWijnen JaapWijnen force-pushed the disable-jemalloc-using-package-traits branch from 3b9d577 to 2566488 Compare February 13, 2026 23:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants